package main

import (
	"database/sql"
	"fmt"
	"game/game-db/mysql"
	"game/game-db/mysql/dao"
	"game/game-db/orm"
	"game/game-db/orm/metag"
	"game/readygo/quickstart/repository"
)

func main() {
	dao.SERVER_IDENTITY = 10004

	sqlDB := mysql.QuickStart("127.0.0.1:3306", "root", "123456", "x1_4_log")
	fmt.Println(sqlDB)

	TestCacheStudent(sqlDB)
	// TestDirectStudent(sqlDB)
}

type Student struct {
	orm.DbEntity
	Id    int64  `orm:"id=AUTOWIRE;name=id;comment=唯一ID"`
	Grade int32  `orm:"comment=年级"`
	Class int32  `orm:"comment=班级"`
	No    int32  `orm:"comment=学号"`
	Name  string `orm:"comment=名字"`
}

func (t *Student) TableMetag() metag.TableMetag {
	tableTag := metag.TableMetag{
		Comment: "学生",
		Indexes: make([]*metag.IndexMetag, 0),
	}
	tableTag.Indexes = append(tableTag.Indexes, &metag.IndexMetag{
		Fields:    []string{"Grade", "Class", "No"},
		IndexType: metag.UNIQUE,
	})
	return tableTag
}

func (t *Student) CacheInfo() *repository.CacheInfo {
	return &repository.CacheInfo{
		RelationFields: []string{"Grade", "Class", "No"},
		AliveTime:      -1,
	}
}

func (t *Student) DirectInfo() *repository.DirectInfo {
	return &repository.DirectInfo{
		RelationFields: []string{"Grade", "Class", "No"},
	}
}

func CreateStudent(grade int32, class int32, no int32, name string) *Student {
	var stu Student
	stu.Grade = grade
	stu.Class = class
	stu.No = no
	stu.Name = name
	return &stu
}

func TestCacheStudent(sqlDB *sql.DB) {

	iidao := dao.NewDefaultBaseDao[*Student](sqlDB, &Student{})
	fmt.Println(iidao.Sql(&Student{}))

	var cacheInfo repository.CacheInfo
	cacheInfo.RelationFields = make([]string, 0)
	cacheInfo.RelationFields = append(cacheInfo.RelationFields, "Grade", "Class", "No")
	cacheRepository := repository.NewCacheRepository[*Student](iidao, &Student{})

	// var stu1 *Student = CreateStudent(2024, 1, 1, "AAA1")
	// var stu2 *Student = CreateStudent(2024, 1, 2, "AAA2")
	// var stu3 *Student = CreateStudent(2024, 2, 1, "AAA3")
	// var stu4 *Student = CreateStudent(2024, 2, 2, "AAA4")
	// var stu5 *Student = CreateStudent(2023, 1, 1, "AAA5")
	// var stu6 *Student = CreateStudent(2023, 2, 1, "AAA6")

	// students := make([]*Student, 0)
	// students = append(students, stu1, stu2, stu3, stu4, stu5, stu6)

	// cacheRepository.InsertAll(students)
	// for _, stu := range students {
	// 	fmt.Printf("%p %s %d\n", stu, stu.Name, stu.Id)
	// }

	fmt.Println("===============1=================")

	studentInCache := cacheRepository.ListByKeys(2024)
	for _, stu := range studentInCache {
		fmt.Printf("%p %s %d\n", stu, stu.Name, stu.Id)
	}
	cacheRepository.Scan()

	fmt.Println("===============2=================")

	stu01, _ := cacheRepository.GetByKeys(2024, 1, 1)
	fmt.Printf("%p %s %d\n", stu01, stu01.Name, stu01.Id)

	// cacheRepository.PrintCache()

	stu06, _ := cacheRepository.GetByKeys(2023, 1, 1)
	// stu06.Name = "AAA7"
	// cacheRepository.Update(stu06)
	fmt.Printf("%p %s %d\n", stu06, stu06.Name, stu06.Id)

	cacheRepository.Scan()

	stu06, _ = cacheRepository.GetByKeys(2023, 1, 1)
	fmt.Printf("%p %s %d\n", stu06, stu06.Name, stu06.Id)

	// cacheRepository.GetByKeys(2024) // will panic
}

func TestDirectStudent(sqlDB *sql.DB) {

	iidao := dao.NewDefaultBaseDao[*Student](sqlDB, &Student{})
	fmt.Println(iidao.Sql(&Student{}))

	var directInfo repository.DirectInfo
	directInfo.RelationFields = make([]string, 0)
	directInfo.RelationFields = append(directInfo.RelationFields, "Grade", "Class", "No")
	cacheRepository := repository.NewDirectRepository[*Student](iidao, &Student{})

	// var stu1 *Student = CreateStudent(2024, 1, 1, "AAA1")
	// var stu2 *Student = CreateStudent(2024, 1, 2, "AAA2")
	// var stu3 *Student = CreateStudent(2024, 2, 1, "AAA3")
	// var stu4 *Student = CreateStudent(2024, 2, 2, "AAA4")
	// var stu5 *Student = CreateStudent(2023, 1, 1, "AAA5")
	// var stu6 *Student = CreateStudent(2023, 2, 1, "AAA6")

	// students := make([]*Student, 0)
	// students = append(students, stu1, stu2, stu3, stu4, stu5, stu6)

	// cacheRepository.InsertAll(students)
	// for _, stu := range students {
	// 	fmt.Printf("%p %s %d\n", stu, stu.Name, stu.Id)
	// }

	fmt.Println("================================")

	studentInCache := cacheRepository.ListByKeys(2024)
	for _, stu := range studentInCache {
		fmt.Printf("%p %s %d\n", stu, stu.Name, stu.Id)
	}

	fmt.Println("================================")

	stu01, _ := cacheRepository.GetByKeys(2024, 1, 1)
	fmt.Printf("%p %s %d\n", stu01, stu01.Name, stu01.Id)

	stu06, _ := cacheRepository.GetByKeys(2023, 1, 1)
	stu06.Name = "AAA7"
	cacheRepository.Update(stu06)
	fmt.Printf("%p %s %d\n", stu06, stu06.Name, stu06.Id)

	stu06, _ = cacheRepository.GetByKeys(2023, 1, 1)
	fmt.Printf("%p %s %d\n", stu06, stu06.Name, stu06.Id)

	// cacheRepository.GetByKeys(2024) // will panic
}
